package com.dcs.cn.gateway.filter;

import cn.com.dcsgo.utils.ResponseResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class GlobalResponseFilter implements GlobalFilter, Ordered {

    private final ObjectMapper objectMapper;

    public GlobalResponseFilter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse originalResponse = exchange.getResponse();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();

        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                System.out.println("进入全局响应过滤器");
                if (body instanceof Flux) {
                    Flux<DataBuffer> fluxBody = (Flux<DataBuffer>) body; // 明确指定泛型类型为DataBuffer
                    return super.writeWith(fluxBody
                            .switchIfEmpty(Mono.defer(() -> {
                                // 处理void类型的响应
                                ResponseResult<Object> result = ResponseResult.success();
                                byte[] newContent;
                                try {
                                    newContent = objectMapper.writeValueAsBytes(result);
                                } catch (JsonProcessingException ex) {
                                    throw new RuntimeException(ex);
                                }
                                originalResponse.getHeaders().setContentLength(newContent.length);
                                return Mono.just(bufferFactory.wrap(newContent));
                            }))
                            .map(dataBuffer -> {
                            byte[] content = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(content);
                            DataBufferUtils.release(dataBuffer);
                            String responseBody = new String(content, StandardCharsets.UTF_8);
                            ServerHttpResponse response = exchange.getResponse();
                            // 检查响应体是否包含ResponseResult的关键字段
                            if (responseBody.contains("\"timestamp\":") &&
                                responseBody.contains("\"status\":") &&
                                responseBody.contains("\"message\":") &&
                                responseBody.contains("\"data\":")) {
                                // 已经是ResponseResult格式，直接返回原始响应
                                originalResponse.setStatusCode(response.getStatusCode());
                                return bufferFactory.wrap(content);
                            }
                            else
                            {
                                // 不是ResponseResult格式，进行封装
                                ResponseResult<Object> result = ResponseResult.success(responseBody);
                                byte[] newContent = null;
                                try {
                                    newContent = objectMapper.writeValueAsBytes(result);
                                } catch (JsonProcessingException ex) {
                                    throw new RuntimeException(ex);
                                }
                                originalResponse.getHeaders().setContentLength(newContent.length);
                                return bufferFactory.wrap(newContent);
                            }
                        }));
                }

                // 处理非Flux类型的响应，通常是void响应
                ResponseResult<Object> result = ResponseResult.success(null);
                byte[] newContent;
                try {
                    newContent = objectMapper.writeValueAsBytes(result);
                } catch (JsonProcessingException ex) {
                    throw new RuntimeException(ex);
                }
                originalResponse.getHeaders().setContentLength(newContent.length);
                return super.writeWith(Mono.just(bufferFactory.wrap(newContent)));
            }
        };

        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }

    @Override
    public int getOrder() {
        return -2;
    }
}